package com.fpswork.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;
import java.util.Hashtable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 
 *身份证校验
 *
 */
public class IDCardUtils {

  private static int[] arrInt = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };

  private static char[] arrChar = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' };
 
  

  public static void main(String[] args) {
	
  }	
  
  /**
   *身份证校验
   *校验身份证位数与身份证是否正确
   */
  public static String  validateIdCard(String idCard){
		if ( idCard.length() == 18  ) {
			return validateIdCard(idCard, idCard.length());
		}else if(idCard.length() == 15){
			return validateIdCard(idCard, idCard.length());
		}else{
			return "身份证号码不是15位或者18位的";
		}
  }

  /**
   *身份证信息
   *根据身份证获取身份证主人的性别
   */
   public static String getSex(String idCard){
     validateIdCard(idCard);
     String sex = "";
     if (idCard.length() == 15) {
       sex = idCard.substring(idCard.length() - 3, idCard.length());
     }
     if (idCard.length() == 18) {
       sex = idCard.substring(idCard.length() - 4, idCard.length() - 1);
     }
     int sexNum = Integer.parseInt(sex) % 2;
     if (sexNum == 0) {
       return "女";
     }
     return "男";
   }
 
   /**
    *身份证信息
    *根据身份证获取身份证主人的地区
    */
   public static String getArea(String idCard){
     validateIdCard(idCard);
     Hashtable<String, String> ht = getAreaCode();
     String area = (String)ht.get(idCard.substring(0, 2));
     return area;
   }
   
   /**
    *身份证信息
    *根据身份证获取身份证主人的生日
    */
   public static String getBirthday(String idCard){
	 validateIdCard(idCard);
     String Ain = "";
     if (idCard.length() == 18) {
       Ain = idCard.substring(0, 17);
     }
     else if (idCard.length() == 15) {
       Ain = idCard.substring(0, 6) + "19" + idCard.substring(6, 15);
     }
 
     String strYear = Ain.substring(6, 10);
     String strMonth = Ain.substring(10, 12);
     String strDay = Ain.substring(12, 14);
     return strYear + "-" + strMonth + "-" + strDay;
   }
 
   
   /*----------------------------------------------下方为检验规则--------------------------------------------*/
   
   
   private static boolean isDate(String strDate)
   {
     if (strDate == null) {
       return false;
     }
     SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
 
     if (strDate.trim().length() != dateFormat.toPattern().length()) {
       return false;
     }
     dateFormat.setLenient(false);
     try
     {
       dateFormat.parse(strDate.trim());
     }
     catch (ParseException pe) {
       return false;
     }
     return true;
   }
 
   private static boolean isNumeric(String str)
   {
     Pattern pattern = Pattern.compile("[0-9]*");
     Matcher isNum = pattern.matcher(str);
 
     return (isNum.matches());
   }
 
 
   

   
   
   private static Hashtable<String, String> getAreaCode()
   {
     Hashtable<String, String> hashtable = new Hashtable<String, String>();
     hashtable.put("11", "北京");
     hashtable.put("12", "天津");
     hashtable.put("13", "河北");
     hashtable.put("14", "山西");
     hashtable.put("15", "内蒙古");
     hashtable.put("21", "辽宁");
     hashtable.put("22", "吉林");
     hashtable.put("23", "黑龙江");
     hashtable.put("31", "上海");
     hashtable.put("32", "江苏");
     hashtable.put("33", "浙江");
     hashtable.put("34", "安徽");
     hashtable.put("35", "福建");
     hashtable.put("36", "江西");
     hashtable.put("37", "山东");
     hashtable.put("41", "河南");
     hashtable.put("42", "湖北");
     hashtable.put("43", "湖南");
     hashtable.put("44", "广东");
     hashtable.put("45", "广西");
     hashtable.put("46", "海南");
     hashtable.put("50", "重庆");
     hashtable.put("51", "四川");
     hashtable.put("52", "贵州");
     hashtable.put("53", "云南");
     hashtable.put("54", "西藏");
     hashtable.put("61", "陕西");
     hashtable.put("62", "甘肃");
     hashtable.put("63", "青海");
     hashtable.put("64", "宁夏");
     hashtable.put("65", "新疆");
     hashtable.put("71", "台湾");
     hashtable.put("81", "香港");
     hashtable.put("82", "澳门");
     hashtable.put("91", "国外");
     return hashtable;
   }
   
   
   public static String  validateIdCard(String idCard, int size){
	    String Ai = "";
		if (idCard.length() != size) {
			return "身份证号码不是"+size+"位";
		}
	   if ((idCard.length() != 18) && (idCard.length() != 15)) {
			return "身份证号码不是15位或者18位的";
	   }
	   if (idCard.length() == 18) {
	      Ai = idCard.substring(0, 17);
	    }
	    else if (idCard.length() == 15) {
	       Ai = idCard.substring(0, 6) + "19" + idCard.substring(6, 15);
	     }
	    if (!(isNumeric(Ai))) {
	       return "15位号码都应为数字 ; 18位号码除最后一位外，都应为数字。";
	     }
	 
	     String strYear = Ai.substring(6, 10);
	     String strMonth = Ai.substring(10, 12);
	     String strDay = Ai.substring(12, 14);
	 
	     if (!(isDate(strYear + "-" + strMonth + "-" + strDay))) {
	      return "生日无效。";
	     }
	 
	     GregorianCalendar gc = new GregorianCalendar();
	     SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
	     try {
	       if ((gc.get(1) - Integer.parseInt(strYear) > 150) || (gc.getTime().getTime() - s.parse(strYear + "-" + strMonth + "-" + strDay).getTime() < 0L))
	       {
	         return "生日不在有效范围。";
	       }
	     } catch (ParseException e) {
	    	 return "异常错误";
	     }
	     if ((Integer.parseInt(strMonth) > 12) || (Integer.parseInt(strMonth) == 0)) {
	       return "月份无效。";
	     }
	     if ((Integer.parseInt(strDay) > 31) || (Integer.parseInt(strDay) == 0)) {
	       return "日期无效。";
	     }
	 
	     Hashtable<String, String> h = getAreaCode();
	     if (h.get(Ai.substring(0, 2)) == null) {
	       return "地区编码无效。";
	     }
	 
	     if (idCard.length() == 18) {
	       char lastPos = idCard.charAt(17);
	       int count = 0;
	 
	      for (int i = 0; i < idCard.length() - 1; ++i) {
	        count += Integer.parseInt(String.valueOf(idCard.charAt(i))) * arrInt[i];
	       }
	       if (arrChar[(count % 11)] == lastPos) {
	         return "ok" ;
	       }
	 
	       return "身份证最后一位验证位出错。";
	     }
	     return " ok" ;
   }
}
